﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Al_FrameWork
{
    /// <summary>
    /// 单例模版类
    /// </summary>
    public class Singleton<T> where T : class
    {
        /// <summary>
        /// 单例
        /// </summary>
        private static T _instance;

        /// <summary>
        /// 静态构造
        /// </summary>
        static Singleton()
        {
            Create();
        }

        /// <summary>
        /// 创建
        /// </summary>
        public static void Create()
        {
            _instance = (T)Activator.CreateInstance(typeof(T), true);
            return;
        }

        /// <summary>
        /// Instance
        /// </summary>
        public static T Instance
        {
            get { return _instance; }
        }

        /// <summary>
        /// 销毁
        /// </summary>
        public static void Destroy()
        {
            _instance = null;
            return;
        }
    }

    public abstract class SingletonMonoBehaviour<T> : MonoBehaviour where T : SingletonMonoBehaviour<T>
    {
        protected static T sInstance = null;
        protected static bool IsCreate = false;
        public static bool s_debugDestroy = false;

        public static T Instance
        {
            get
            {
                if (!Application.isPlaying)
                {
                    return null;
                }

                if (s_debugDestroy)
                {
                    return null;
                }

                CreateInstance();
                return sInstance;
            }
        }

        protected virtual void Awake()
        {
            // Debug.Log("Awake===================");
            if (sInstance = null)
            {
                sInstance = this as T;
                IsCreate = true;
                Init();
            }
        }

        protected virtual void Init()
        {
            // sInstance.InitData();
        }

        public abstract void ClearData();

        public abstract void InitData();

        protected void OnDestroy()
        {
            // Debug.Log("monoSingleton OnDestroy");
            sInstance = null;
            IsCreate = false;
        }

        private void OnApplicationQuit()
        {
            sInstance = null;
            IsCreate = false;
        }

        public static void CreateInstance()
        {
            if (IsCreate == true)
                return;

            IsCreate = true;
            T[] managers = GameObject.FindObjectOfType(typeof(T)) as T[];

            if (null != managers)
            {
                if (managers.Length != 0)
                {
                    if (managers.Length == 1)
                    {
                        sInstance = managers[0];
                        sInstance.gameObject.name = typeof(T).Name;
                        DontDestroyOnLoad(sInstance.gameObject);
                        return;
                    }
                    else
                    {
                        foreach (T manager in managers)
                        {
                            Destroy(manager.gameObject);
                        }
                    }
                }
            }

            GameObject g0 = new GameObject(typeof(T).Name, typeof(T));
            sInstance = g0.GetComponent<T>();
            DontDestroyOnLoad(sInstance.gameObject);
            sInstance.Init();
        }

        public static void ReleaseInstance()
        {
            if (sInstance != null)
            {
                sInstance.ClearData();
                Destroy(sInstance.gameObject);
                sInstance = null;
                IsCreate = false;
            }
        }
    }
}